import sys
import logging
import pandas as pd
import os
import time

from PyQt5.QtWidgets import (
    QApplication, QWidget, QLabel, QLineEdit, QPushButton,
    QVBoxLayout, QHBoxLayout, QMessageBox, QTextEdit, QCheckBox
)
from PyQt5.QtCore import Qt, QThread, pyqtSignal

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

from config import DRIVER_PATH, LOGIN_URL
from crawler.browser import Browser

logging.basicConfig(format='[%(levelname)s] %(message)s', level=logging.INFO)

class ScrapeThread(QThread):
    progress = pyqtSignal(str)
    finished = pyqtSignal(bool, str)

    def __init__(self, username, password, course, subnode, headless):
        super().__init__()
        self.username = username
        self.password = password
        self.course = course
        self.subnode = subnode
        self.headless = headless

    def run(self):
        try:
            self.progress.emit("Launching browser...")
            browser = Browser(driver_path=DRIVER_PATH, headless=self.headless)
            wait = WebDriverWait(browser.driver, 20)

            self.progress.emit("Opening login page...")
            browser.open_url(LOGIN_URL)

            self.progress.emit("Switching to password login tab...")
            wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "span[onclick='loginForPwd()']"))).click()

            self.progress.emit("Entering credentials...")
            wait.until(EC.element_to_be_clickable((By.ID, "username"))).send_keys(self.username)
            wait.until(EC.element_to_be_clickable((By.ID, "pwd"))).send_keys(self.password)

            self.progress.emit("Submitting login and solving CAPTCHA...")
            wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button[onclick='logincheck()']"))).click()
            browser.solve_slider((By.CSS_SELECTOR, ".code-btn-img.code-btn-m"))
            wait.until(lambda d: d.current_url != LOGIN_URL)
            time.sleep(1)

            self.progress.emit("Closing notifications if any...")
            browser.close_notification_popup()

            self.progress.emit("Navigating to 教学平台...")
            wait.until(EC.element_to_be_clickable((By.LINK_TEXT, "教学平台"))).click()
            wait.until(EC.url_contains("#/curriculumSpace"))
            browser.close_notification_popup()

            self.progress.emit(f"Selecting course [auto]{self.course}...")
            browser.select_course(self.course, timeout=15)
            wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "div[role='treeitem']")))

            self.progress.emit(f"Selecting submission {self.subnode}...")
            browser.select_submission(self.subnode, timeout=15)

            self.progress.emit("Loading submission details...")
            browser.view_submission_details(timeout=15)

            self.progress.emit("Extracting all submissions...")
            subs = browser.extract_all_submissions(timeout=20)

            self.progress.emit(f"Found {len(subs)} entries. Saving to Excel...")
            df = pd.DataFrame(subs)
            outfile = os.path.join(os.getcwd(), "submissions.xlsx")
            df.to_excel(outfile, index=False)

            browser.close()
            self.finished.emit(True, outfile)
        except Exception as e:
            logging.exception("Error during scraping")
            try:
                browser.close()
            except:
                pass
            self.finished.emit(False, str(e))

class KKWCrawlerGUI(QWidget):
    def __init__(self):
        super().__init__()
        self.init_ui()

    def init_ui(self):
        self.setWindowTitle("KKW Crawler")
        self.setFixedSize(500, 420)

        layout = QVBoxLayout(self)

        # Username
        hl = QHBoxLayout()
        hl.addWidget(QLabel("Username:"))
        self.username_input = QLineEdit()
        hl.addWidget(self.username_input)
        layout.addLayout(hl)

        # Password
        hl = QHBoxLayout()
        hl.addWidget(QLabel("Password:"))
        self.password_input = QLineEdit()
        self.password_input.setEchoMode(QLineEdit.Password)
        hl.addWidget(self.password_input)
        layout.addLayout(hl)

        # Course suffix
        hl = QHBoxLayout()
        hl.addWidget(QLabel("Course suffix:"))
        self.course_input = QLineEdit()
        hl.addWidget(self.course_input)
        layout.addLayout(hl)

        # Submission title
        hl = QHBoxLayout()
        hl.addWidget(QLabel("Submission title:"))
        self.submission_input = QLineEdit()
        hl.addWidget(self.submission_input)
        layout.addLayout(hl)

        # Headless checkbox
        self.headless_checkbox = QCheckBox("Headless Mode")
        self.headless_checkbox.setChecked(True)
        layout.addWidget(self.headless_checkbox)

        # Start button
        self.start_btn = QPushButton("Start Scraping")
        self.start_btn.clicked.connect(self.start_scrape)
        layout.addWidget(self.start_btn)

        # Log area
        self.log_area = QTextEdit()
        self.log_area.setReadOnly(True)
        layout.addWidget(self.log_area)

    def log(self, msg: str):
        self.log_area.append(msg)

    def show_error(self, title: str, msg: str):
        QMessageBox.critical(self, title, msg)

    def start_scrape(self):
        username = self.username_input.text().strip()
        password = self.password_input.text().strip()
        course   = self.course_input.text().strip()
        subnode  = self.submission_input.text().strip()
        headless = self.headless_checkbox.isChecked()

        if not all([username, password, course, subnode]):
            self.show_error("Input Error", "All fields are required.")
            return

        self.start_btn.setEnabled(False)
        self.log_area.clear()

        # Kick off thread
        self.thread = ScrapeThread(username, password, course, subnode, headless)
        self.thread.progress.connect(self.log)
        self.thread.finished.connect(self.on_finished)
        self.thread.start()

    def on_finished(self, success: bool, info: str):
        if success:
            QMessageBox.information(self, "Complete", f"Scraping finished. Data saved to {info}.")
        else:
            self.show_error("Error", info)
        self.start_btn.setEnabled(True)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    gui = KKWCrawlerGUI()
    gui.show()
    sys.exit(app.exec_())